#pragma once
#define __STDC_CONSTANT_MACROS
extern "C"{
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
};
#include "SDL/SDL.h"
#include <vector>
#include <string>

using namespace std;

#define SDL_AUDIO_BUFFER_SIZE 1024

class BufferingThread
{

public:
	~BufferingThread();	
	
	static BufferingThread * instance();
	static BufferingThread * other_instance();
	static void set_preload_status(bool _s) { _is_preloaded = _s;}
	static bool preload_status(){return _is_preloaded;}
	static void change_current(){_current = 1- _current;}
	void run();

	void buffer_size(int size){_buf_size = size;}
	void channel(int c){_channel = c;}
	int w(){ return _w;}
	int h(){ return _h;}
	bool is_stop(){return _is_stop;}

	int used_byte();
	int free_byte();
	float usage();
	int64_t duration();
	bool is_full();

	void ffmpeg_init();
	bool open(string);
	void close();
	void seek(int frame);
	void seek(double rel_time);
	void buffering();
	int read(uint8_t *buf,int pitch);

	string last_err_msg(){return _err;}

	
private:
	BufferingThread();

	static BufferingThread *obj[2];
	static int _current;
	static bool _is_preloaded;
	

	string err_msg(int code, const char * desc);

	bool _is_stop;
	bool _is_seek;

	string _file;

	SDL_Thread *_thread;
	SDL_mutex *_mutex;
	SDL_cond *_cond1;
	SDL_cond *_cond2;

	int _head;
	int _tail;

	
	int _buf_size;
	int _w;
	int _h;
	int _channel;
	int _v_stream;

	bool _full;
	
	uint8_t **_buffer;
	
	uint8_t *_frame_buf;
	bool *_check;
	int *_pts;
	
	int64_t _seek_target;

	AVFormatContext *_format_ctx;
	AVCodecContext *_codec_ctx;
	
	AVCodec *_codec;
	AVFrame *_frame;
	AVFrame *_frame_RGB;

	string _err;
			
};

